#!/bin/bash
#author: xieziqiang
#email: xie.zi.qiang@outlook.com

# https://artifacts.elastic.co/downloads/kibana/kibana-8.14.3-linux-x86_64.tar.gz
# https://artifacts.elastic.co/downloads/kibana/kibana-7.17.22-linux-x86_64.tar.gz

# when KIBANA_SSL="true", this script need running in server which has installed elasticsearch or you can put your p12 cert to $ES_HTTP_CERT dir
set -ue
#****** vars *********#
KIBANA_VERSION="8.14.3"
KIBANA_INSTALL_PATH="/usr/local"
KIBANA_PORT=5601
KIBANA_USER="kibana"
KIBANA_SSL="true" # true or false

ES_HOSTS='["https://10.0.0.50:9200","https://10.0.0.51:9200","https://10.0.0.52:9200"]'

ES_SSL="true" # true or false
ES_KIBANA_USER="kibana_system"
ES_KIBANA_PASSWD="TVzRHXDFKxBPKqIXVFFA"
ES_CACERT="/root/ca.pem" # need 
ES_CACERT_NAME="${ES_CACERT##*/}"
#**** optional vars, effective when KIBANA_SSL="true" *******#
#     you can use elasticsearch-certutil to generate cert
KIBANA_HTTP_CERT="/usr/local/elasticsearch/config/certs/kibana-http.p12" # need p12 format
KIBANA_HTTP_CERT_PASSWD=""
KIBANA_HTTP_CERT_NAME="${KIBANA_HTTP_CERT##*/}"
#****** functions *********#
color() {
    local message="$1"
    local status="$2"
    local terminal_width
    terminal_width=$(tput cols)
    local middle_column=$(( terminal_width / 2))
    local SETCOLOR_SUCCESS="\033[1;32m"  # 绿色
    local SETCOLOR_FAILURE="\033[1;31m"  # 红色
    local SETCOLOR_WARNING="\033[1;33m"  # 黄色
    local SETCOLOR_NORMAL="\033[0m"      # 重置颜色
    printf '%s\n\033[%sG' "${message}"  "${middle_column}"
    # Print the status message
    printf "["
    case ${status} in
        success|0)
            echo -en  "${SETCOLOR_SUCCESS}  OK  "
            ;;
        failure|1)
            echo -en  "${SETCOLOR_FAILURE}FAILED"
            ;;
        *)
            echo -en "${SETCOLOR_WARNING}WARNING"
            ;;
    esac
    echo -e "${SETCOLOR_NORMAL}]"
}

judge_current_user () {
    if [ "$(id -u)" = "0" ];then
        color "current user is administrator" 0
    else
        color "current user is not administrator" 1
        exit
    fi
}

create_user () {
    if ! id "$1" &> /dev/null;then
        useradd -r -M -s /sbin/nologin "$1" \
        && color "$1 user is created." 0 \
        || { color "$1 user create failed.";exit; }
    else
        color "$1 user is existed." 2
    fi
}

create_dir () {
    local i
    for i in "$@";do
        if [ ! -d "$i" ];then
            mkdir -pv "$i" && color "$i dir is created" 0
        else
            color "$i dir is existed." 2
        fi
    done
}

process_file () {
    if [ "${KIBANA_SSL}" = "true" ];then
        if ! [ -e "${KIBANA_HTTP_CERT}" ];then
            color "${KIBANA_HTTP_CERT} is not exist." 1
            exit
        fi
    fi

    if [ "${ES_SSL}" = "true" ];then
        if ! [ -e "$ES_CACERT" ];then 
            color "$ES_CACERT is not exist." 1
            exit
        fi
    fi

    if [ ! -e "kibana-${KIBANA_VERSION}-linux-x86_64.tar.gz" ];then
        color "current directory dont exist kibana-${KIBANA_VERSION}-linux-x86_64.tar.gz" 1
        exit
    fi

    tar -xvf "kibana-${KIBANA_VERSION}-linux-x86_64.tar.gz" -C "${KIBANA_INSTALL_PATH}"
    if [ ${KIBANA_VERSION%%.*} -eq 8 ];then
        ln -nfs ${KIBANA_INSTALL_PATH}/kibana-${KIBANA_VERSION} ${KIBANA_INSTALL_PATH}/kibana
    elif [ ${KIBANA_VERSION%%.*} -eq 7 ];then
        ln -nfs ${KIBANA_INSTALL_PATH}/kibana-${KIBANA_VERSION}-linux-x86_64 ${KIBANA_INSTALL_PATH}/kibana
    else
        color "unknown kibana version" 1
        exit
    fi
}

set_kibana_configfile () {
    if [ "${KIBANA_SSL}" = "true" ];then
        \cp ${KIBANA_HTTP_CERT} ${KIBANA_INSTALL_PATH}/kibana/config/
        chmod 600 "${KIBANA_INSTALL_PATH}/kibana/config/${KIBANA_HTTP_CERT_NAME}"
    fi
    if [ "${ES_SSL}" = "true" ];then
        \cp  "${ES_CACERT}"  ${KIBANA_INSTALL_PATH}/kibana/config/
        chmod 600 "${KIBANA_INSTALL_PATH}/kibana/config/${ES_CACERT_NAME}"
    fi
    cp ${KIBANA_INSTALL_PATH}/kibana/config/{kibana.yml,kibana.yml.bak}
    cat > ${KIBANA_INSTALL_PATH}/kibana/config/kibana.yml<<EOF
server.port: ${KIBANA_PORT}
server.host: "0.0.0.0"
pid.file: ${KIBANA_INSTALL_PATH}/kibana/kibana.pid
logging:
  appenders:
    file:
      type: file
      fileName: ${KIBANA_INSTALL_PATH}/kibana/kibana.log
      layout:
        type: json
  root:
    level: info
    appenders:
      - default
      - file

server.ssl.enabled: ${KIBANA_SSL}
#server.ssl.certificate: /path/to/your/server.crt
#server.ssl.key: /path/to/your/server.key
server.ssl.keystore.path: "${KIBANA_INSTALL_PATH}/kibana/config/${KIBANA_HTTP_CERT_NAME}"
server.ssl.keystore.password: "${KIBANA_HTTP_CERT_PASSWD}"

#elasticsearch.hosts: ["http://localhost:9200"]
#elasticsearch.username: "kibana_system"
#elasticsearch.password: "pass"

elasticsearch.hosts: $ES_HOSTS
elasticsearch.username: "$ES_KIBANA_USER"
elasticsearch.password: "$ES_KIBANA_PASSWD"
elasticsearch.ssl.certificateAuthorities: [ "${KIBANA_INSTALL_PATH}/kibana/config/${ES_CACERT_NAME}" ]
# To disregard the validity of SSL certificates, change this setting's value to 'none'.
elasticsearch.ssl.verificationMode: full
EOF

    if [ "${KIBANA_SSL}" = "false" ];then
        sed -i '/^server.ssl./s/^/#/g' ${KIBANA_INSTALL_PATH}/kibana/config/kibana.yml
    fi

    if [ "${ES_SSL}" = "false" ];then
        sed -i -e '/^elasticsearch.username:/s/^/#/g' \
        -e '/^elasticsearch.password:/s/^/#/g' \
        -e '/^elasticsearch.ssl.certificateAuthorities:/s/^/#/g' \
        -e '/^elasticsearch.ssl.verificationMode:/s/^/#/g' \
        ${KIBANA_INSTALL_PATH}/kibana/config/kibana.yml
    fi

    chown -HR ${KIBANA_USER}:${KIBANA_USER}  ${KIBANA_INSTALL_PATH}/kibana
}


init_kibana_service () {
    cat > /lib/systemd/system/kibana.service<<EOF
[Unit]
Description=Kibana
Documentation=https://www.elastic.co
Wants=network-online.target
After=network-online.target

[Service]
Type=simple
User=${KIBANA_USER}
Group=${KIBANA_USER}
Environment=KBN_HOME=${KIBANA_INSTALL_PATH}/kibana
Environment=KBN_PATH_CONF=${KIBANA_INSTALL_PATH}/kibana/config
ExecStart=${KIBANA_INSTALL_PATH}/kibana/bin/kibana
PrivateTmp=true
Restart=on-failure
RestartSec=3
StartLimitBurst=3
StartLimitInterval=60
WorkingDirectory=${KIBANA_INSTALL_PATH}/kibana
StandardOutput=journal
StandardError=inherit

[Install]
WantedBy=multi-user.target
EOF
    systemctl daemon-reload
    systemctl enable kibana.service
    systemctl start kibana.service \
    && color "kibana start sucess!" 0 \
    || { color "kibana start fail." 1; exit; }
}

main () {
    if ! [[ ${KIBANA_SSL} =~ ^true$|^false$ ]];then
        color "KIBANA_SSL var set is wrong,check script." 1
        exit
    fi
    if ! [[ ${ES_SSL} =~ ^true$|^false$ ]];then
        color "ES_SSL var set is wrong,check script." 1
        exit
    fi
    judge_current_user
    create_user ${KIBANA_USER}
    process_file
    set_kibana_configfile
    init_kibana_service
}

main